﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TShockAPI;
using TerrariaApi.Server;
using Microsoft.Xna.Framework;
using System.Data.Linq;
using System.IO;
using Terraria;
using Terraria.Localization;
using Newtonsoft.Json;
using TShockAPI.Hooks;
using BeanPoints;
using static TShockAPI.GetDataHandlers;

namespace BeanShop
{
    [ApiVersion(2, 1)]
    public class Main : TerrariaPlugin
    {
        public override string Name => "BeanShop";

        public override Version Version => new Version(2, 0,5);

        public override string Author => "豆沙";

        public override string Description => "A shop plugin";
        public static List<ShopChest> shops = new List<ShopChest>();
        public static List<ShopKeeper> keepers = new List<ShopKeeper>();
        public Main(Terraria.Main game) : base(game)
        {
        }
        public override void Initialize()
        {
            #region --CMD--
            Commands.ChatCommands.Add(new Command("bs.user", bs, "bs"));
            Commands.ChatCommands.Add(new Command("bs.admin", bsadmin, "bsadmin"));
            #endregion
            #region --Hooks-
            ServerApi.Hooks.ServerJoin.Register(this, OnJoin);
            ServerApi.Hooks.ServerChat.Register(this, OnChat);
            ServerApi.Hooks.ServerLeave.Register(this, OnLeave);
            ServerApi.Hooks.NetGetData.Register(this,OnGetData);
            GetDataHandlers.PlaceChest += OnPlaceChest;
            GetDataHandlers.TileEdit += OnTileEdit;
            GeneralHooks.ReloadEvent += OnReload;
            ConfigUtils.InitializeConfig();
            #endregion
        }
        //打开箱子部分在这里
        #region --OnGetData--
        private void OnGetData(GetDataEventArgs args)
        {

            if (args.MsgID == PacketTypes.ChestGetContents)
            {
                var plr = TShock.Players[args.Msg.whoAmI];
                using (var reader = new BinaryReader(new MemoryStream(args.Msg.readBuffer, args.Index, args.Length)))
                {
                    var X = reader.ReadInt16();
                    var Y = reader.ReadInt16();
                    var skplr = keepers.Find(p => p.Player.Name == plr.Name);
                    var bplr = BeanPlayer.GetBeanPlayer(plr.Name);
                    var trashitem = plr.TPlayer.trashItem;
                    var chest = shops.Find(c => c.TileX == X && c.TileY == Y + 1);
                    if (chest != null)
                    {
                        chest.RealChestID = Terraria.Chest.FindChest(X, Y);
                        chest.RealChest = Terraria.Main.chest[chest.RealChestID];
                        switch (skplr.Status)
                        {
                            case KeeperStatus.Common:
                                if (!skplr.IsOwner(chest))
                                {
                                    switch (chest.Type)
                                    {
                                        case ShopType.Sell://玩家进行购买操作部分
                                            args.Handled = true;
                                            chest.IsSelected = true;
                                            skplr.SendInfoMessage("请在聊天框里输入要购买的数量（输入cancel取消购买）");
                                            skplr.BuyType(chest.ID);
                                            break;
                                        case ShopType.Buy://玩家进行收购操作部分
                                            if (chest.IsFull)
                                            {
                                                skplr.SendErrorMessage("该商店箱子已满，无法收购");
                                                return;
                                            }
                                            if (chest.GoodsID != 0 && chest.GoodPrice != 0)
                                            {
                                                if (trashitem.netID == chest.GoodsID)
                                                {
                                                    var owner = chest.ReturnOwnerAccountNoTP();
                                                    var total = trashitem.stack * chest.GoodPrice;
                                                    var tsowner = TSPlayer.FindByNameOrID(owner.Name);
                                                    if (owner.Points >= total)
                                                    {
                                                        chest.IsSelected = true;
                                                        chest.IntoChest(trashitem);
                                                        bplr.AddPoints(total);
                                                        bplr.ShowChangeInfo(ChangeType.收入, total);
                                                        if (tsowner.Count != 0)
                                                        {
                                                            owner.Player = TSPlayer.FindByNameOrID(owner.Name)[0];
                                                            owner.SendInfoMessage($"玩家 [{skplr.Player.Name}] 在你的商店 (ID:{chest.ID}) 出售了 [i:{trashitem.netID}]*{trashitem.stack} 您支付了 {total} {BeanPoints.ConfigUtils.config.CurrencyName}");
                                                            owner.ShowChangeInfo(ChangeType.支出, total);
                                                        }
                                                        owner.DecreasePoints(total);
                                                        skplr.SendSuccessMessage($"成功回收了 {trashitem.stack} 个 [i:{trashitem.netID}]  总共 {total} {BeanPoints.ConfigUtils.config.CurrencyName}");
                                                        skplr.ClearTrashItem();
                                                        chest.IsSelected = false;
                                                    }
                                                    else
                                                    {
                                                        skplr.SendErrorMessage("对方账户余额不足，无法收购");
                                                    }
                                                }
                                                else
                                                {
                                                    skplr.SendErrorMessage("请确保垃圾桶里的物品为对应的商店物品");
                                                }
                                            }
                                            else
                                            {
                                                skplr.SendErrorMessage("该商店未设置物品或价格");
                                            }
                                            args.Handled = true;
                                            break;
                                        case ShopType.Common:
                                            if (!skplr.IsOwner(chest))
                                            {
                                                skplr.SendInfoMessage("这不是你的箱子不能打开");
                                                args.Handled = true;
                                            }
                                            break;
                                    }
                                }
                                else //主人部分
                                {
                                    //chest = shops.Find(s => s.TileX == X && s.TileY - 1 == Y);
                                    if (chest.IsSelected)
                                    {
                                        skplr.SendInfoMessage("有玩家正在选中你的商店,无法打开");
                                        args.Handled = true;
                                    }
                                    else
                                    {
                                        chest.Open(plr.Index, chest);
                                    }
                                }
                                break;
                            case KeeperStatus.UpItem:
                                if (!skplr.IsOwner(chest)&&chest!=null)
                                {
                                    skplr.SendErrorMessage("你不是这个商店的主人");
                                    skplr.SetCommonType();
                                    args.Handled = true;
                                    return;
                                }
                                if (chest.RealChest != null && chest.RealChest.item[0].netID != 0)
                                {
                                    int id = chest.RealChest.item[0].netID;
                                    chest.GoodsID = id;
                                    skplr.SendInfoMessage($"成功将商品设置为[i:{id}]");
                                    ConfigUtils.UpdateShops();
                                }
                                else
                                {
                                    skplr.SendInfoMessage("请在箱子第一格放置要设置的[出售物品]或[收购物品]");
                                }
                                skplr.SetCommonType();
                                args.Handled = true;
                                break;
                            case KeeperStatus.SetBuy:
                                if (chest != null)
                                {
                                    if (!skplr.IsOwner(chest))
                                    {
                                        args.Handled = true;
                                        skplr.SendErrorMessage("你不是这个商店的主人");
                                        return;
                                    }
                                    chest.SetBuyType();
                                    skplr.SendInfoMessage($"成功设置ID:{chest.ID} 的商店为 [收购]");
                                    ConfigUtils.UpdateShops();
                                }
                                else
                                {
                                    skplr.SendErrorMessage("这不是个箱子商店呢");
                                }
                                skplr.SetCommonType();
                                args.Handled = true;
                                break;
                            case KeeperStatus.SetSell:
                                if (chest != null)
                                {
                                    if (!skplr.IsOwner(chest))
                                    {
                                        args.Handled = true;
                                        skplr.SendErrorMessage("你不是这个商店的主人");
                                        return;
                                    }
                                    chest.SetSellType();
                                    skplr.SendInfoMessage($"成功设置ID:{chest.ID} 的商店为 [出售]");
                                    ConfigUtils.UpdateShops();
                                }
                                else
                                {
                                    skplr.SendErrorMessage("这不是个箱子商店呢");
                                }
                                skplr.SetCommonType();
                                args.Handled = true;
                                break;
                            default:
                                args.Handled = true;
                                break;
                        }
                    }
                }
            }
            if (args.MsgID == PacketTypes.ChestItem)
            {
                using (var reader = new BinaryReader(new MemoryStream(args.Msg.readBuffer, args.Index, args.Length)))
                {
                    var chestid = reader.ReadInt16();
                    var chest = new ShopChest();
                    if (shops.Exists(s => s.RealChestID == chestid))
                    {
                        chest=shops.Find(s=>s.RealChestID==chestid);
                        int slotCount=0;
                        for (int i = 0; i < chest.RealChest.item.Length; i++)
                        {
                            var item = chest.RealChest.item[i];
                            if (item.netID!=0&&item.stack>=99)
                            {
                                slotCount++;
                            }
                        }
                        if (slotCount!=40)
                        {
                            chest.IsFull = false;
                        }
                    }
                }
            }
        }
        #endregion
        #region --OnTileEdit--
        private void OnTileEdit(object sender,GetDataHandlers.TileEditEventArgs args) {
            if (args.Action==EditAction.KillTile)
            {
                var skplr = keepers.Find(k=>k.Player.Name==args.Player.Name);
                var chest = shops.Find(c => (c.TileX == args.X && c.TileY == args.Y) || (c.TileX == args.X - 1 && c.TileY == args.Y) || (c.TileX == args.X && c.TileY == args.Y + 1) || (c.TileX == args.X - 1 && c.TileY == args.Y + 1));
                if (chest!=null)
                {
                    int id = Terraria.Chest.FindChest(chest.TileX,chest.TileY-1) ;
                    if (id!=-1)
                    {
                        chest.RealChestID = id;
                        chest.RealChest = Terraria.Main.chest[chest.RealChestID];
                        //args.Player.SendInfoMessage($"{chest.RealChest.item[0].Name}");
                    }
                    switch (skplr.Status)
                    {
                        case KeeperStatus.SetPrice:
                            skplr.SetCurrentShopID(chest.ID);
                            skplr.SendInfoMessage("请在聊天框输入价格");
                            break;
                        case KeeperStatus.Common:
                            skplr.SendInfoMessage(chest.ShowShopInfo());
                            break;
                        case KeeperStatus.RemoveShop:
                            if (skplr.IsOwner(chest))
                            {
                                shops.Remove(chest);
                                ConfigUtils.UpdateShops();
                                skplr.SetCommonType();
                                skplr.SendSuccessMessage($"成功移除 ID:{chest.ID} 号商店 店主{chest.Owner}");
                            }
                            else {
                                skplr.SendErrorMessage("这不是你的商店");
                                skplr.SetCommonType();
                            }
                            break;
                    }
                    args.Handled = true;
                }
            }
        }
        #endregion
        #region --OnReload--
        private void OnReload(ReloadEventArgs args)
        {
            ConfigUtils.ReloadConfig();
            args.Player.SendMessage("[BeanShop] 重载完成", Color.DarkTurquoise);
        }
        #endregion
        #region --OnChat--
        private void OnChat(ServerChatEventArgs args)
        {
            
            if (args.Text.IndexOf(TShock.Config.CommandSilentSpecifier) == 0 || args.Text.IndexOf(TShock.Config.CommandSpecifier) == 0)
            {
                return;
            }
            var plr = TShock.Players[args.Who];
            var skplr = keepers.Find(p => p.Player.Name == plr.Name);
            var bplr = BeanPlayer.GetBeanPlayer(skplr.Player.Name);
            var chest = shops.Find(c => c.ID == skplr.CurrentShopID);
            if (args.Text == "cancel")
            {
                
                skplr.SetCommonType();
                skplr.SendSuccessMessage("已取消操作");
                args.Handled = true;
            }
            switch (skplr.Status)
            {
                case KeeperStatus.SetPrice:
                    int price;
                    if (int.TryParse(args.Text, out price) && price >= 0)
                    {
                        if (skplr.IsOwner(chest))
                        {
                            chest.GoodPrice = price;
                            skplr.SetCommonType();
                            skplr.SendSuccessMessage("设置成功");
                            ConfigUtils.UpdateShops();
                        }
                        else {
                            skplr.SendErrorMessage("你不是该商店的主人");
                            skplr.SetCommonType();
                        }
                    }
                    else {
                        skplr.SendErrorMessage("请输入非负数数字");
                    }
                    args.Handled = true;
                    break;
                case KeeperStatus.Buy:
                    int aimcount;
                    if (int.TryParse(args.Text, out aimcount) &&aimcount>=0)
                    {
                        if (aimcount <= chest.GetTotal()&&bplr.Points>=aimcount*chest.GoodPrice)
                        {
                            if (chest.OutChest(TShock.Players[args.Who], aimcount))
                            {
                                int total = aimcount * chest.GoodPrice;
                                var bpowner = chest.ReturnOwnerAccountNoTP();
                                bplr.DecreasePoints(total);
                                bpowner.AddPoints(total);
                                bplr.ShowChangeInfo(ChangeType.支出,total);
                                if (TSPlayer.FindByNameOrID(bpowner.Name).Count!=0)
                                {
                                    var ownerPlr=TSPlayer.FindByNameOrID(bpowner.Name)[0];
                                    bpowner.Player = ownerPlr;
                                    bpowner.SendInfoMessage($"玩家 [{bplr.Name}] 在你的商店(ID:{chest.ID}) 购买了 [i:{chest.GoodsID}]*{aimcount} 获得 {total} {BeanPoints.ConfigUtils.config.CurrencyName}");
                                    bpowner.ShowChangeInfo(ChangeType.收入,total);
                                }
                                skplr.SetCommonType();
                                skplr.SendSuccessMessage($"成功购买 [i:{chest.GoodsID}]*{aimcount} 花费 {total} {BeanPoints.ConfigUtils.config.CurrencyName}");
                                chest.IsSelected = false;
                            }
                        }
                        else {
                            skplr.SendErrorMessage("该商店库存不足或您的余额不足");
                        }
                    }
                    else
                    {
                        skplr.SendErrorMessage("请输入非负数数字");
                    }
                    args.Handled = true;
                    break;
            }
        }
        #endregion
        #region --OnLeave--
        private void OnLeave(LeaveEventArgs args)
        {
            var tsplr = new TSPlayer(args.Who);
            var skplr = keepers.Find(p => p.Player.Name == tsplr.Name);
            if (keepers.Contains(skplr))
            {
                keepers.Remove(skplr);
            }
        }
        #endregion
        #region --OnPlaceChest--
        private void OnPlaceChest(object sender,GetDataHandlers.PlaceChestEventArgs args) {
            //flag=0 放置箱子 =1破坏箱子
            //判断玩家处于创建商店状态并且金钱大于配置文件金钱
            var flag = args.Flag;
            var tileX = args.TileX;
            var tileY = args.TileY;
            var skplr = keepers.Find(p=>p.Player.Name==args.Player.Name);
            var bplr = BeanPlayer.GetBeanPlayerNoTP(skplr.Player.Name);
            var chest = shops.Find(c => (c.TileX == tileX && c.TileY == tileY) || (c.TileX == tileX - 1 && c.TileY == tileY) || (c.TileX == tileX && c.TileY == tileY + 1) || (c.TileX == tileX - 1 && c.TileY == tileY + 1));
            switch (skplr.Status)
            {
                case KeeperStatus.Common:
                    if (flag == 1 && chest != null)//无这段宝箱会被敲掉
                    {
                        //args.Player.SendInfoMessage("敲掉宝箱已触发");
                        skplr.SendInfoMessage("这是一个商店箱子,要敲掉请先输入/bs remove");
                        args.Handled = true;
                    }
                    break;
                case KeeperStatus.CreateShop:
                                bplr.DecreasePoints(ConfigUtils.config.OpenRequireMoney);
                                shops.Add(new ShopChest(ShopChest.GetMaxShopID(shops) + 1, "", ShopType.Common, tileX, tileY, args.Player.Name, -1));
                                skplr.SendMessage("成功创建商店", Color.DarkTurquoise);
                                skplr.SetCommonType();
                                ConfigUtils.UpdateShops();
                            break;
                case KeeperStatus.RemoveShop:
                    if (!skplr.IsOwner(chest))
                    {
                        skplr.SendErrorMessage("这不是你的商店,无法移除");
                        skplr.SetCommonType();
                        args.Handled = true;
                    }
                    break;
                default:
                    if (flag == 1 && chest != null)//无这段宝箱会被敲掉
                    {
                        args.Handled = true;
                    }
                    break;
                    }
            }
        #endregion
        #region --OnJoin--
        private void OnJoin(JoinEventArgs args)
        {
            var tsplr = TShock.Players[args.Who];
            var skplr = new ShopKeeper(tsplr, KeeperStatus.Common, 0);
            if (!keepers.Contains(skplr))
            {
                keepers.Add(skplr);
            }
        }
        #endregion
        #region --BS--
        private void bs(CommandArgs args)
        {
            if (args.Parameters.Count < 1)
            {
                args.Player.SendErrorMessage("输入/bs help 查看帮助信息");
                return;
            }
            var skplr = keepers.Find(p => p.Player.Name == args.Player.Name);
            var bpplr = BeanPlayer.GetBeanPlayerNoTP(skplr.Player.Name);
            switch (args.Parameters[0])
            {
                case "help":
                    var helptext = new StringBuilder();
                    helptext.AppendLine("----[插件帮助]----");
                    helptext.AppendLine("/bs create 创建商店");
                    helptext.AppendLine("/bs list 列出你的商店信息");
                    helptext.AppendLine("/bs set [buy/sell] 设置收购/出售商店");
                    helptext.AppendLine("/bs remove 移除商店");
                    helptext.AppendLine("/bs setitem 上架商品");
                    helptext.AppendLine("/bs setprice 设置价格");
                    args.Player.SendMessage(helptext.ToString(), Color.DarkTurquoise);
                    break;
                case "list":
                    var keeperShopList = new StringBuilder();
                    keeperShopList.AppendLine($"您的商店列表-->");
                    foreach (var item in shops)
                    {
                        if (item.Owner == args.Player.Name)
                        {
                            keeperShopList.AppendLine($"ID:{item.ID} 类型:{item.ReturnType()} 商品:[i:{item.GoodsID}] 价格:{item.GoodPrice}");
                        }
                    }
                    args.Player.SendMessage(keeperShopList.ToString(), Color.DarkTurquoise);
                    break;
                case "create":
                    if (shops.Where(s => s.Owner == skplr.Player.Name).ToList().Count>=ConfigUtils.config.MaxOwnCount)
                    {
                        skplr.SendInfoMessage($"你拥有的商店数量已超过 {ConfigUtils.config.MaxOwnCount}");
                        return;
                    }
                    if (bpplr.Points >= ConfigUtils.config.OpenRequireMoney)
                    {
                        skplr.SetCreateShopType();
                        args.Player.SendMessage("请放置一个箱子,来创建一个箱子商店,输入cancel停止操作", Color.DarkTurquoise);
                    }
                    else {
                        skplr.SendErrorMessage($"你的{BeanPoints.ConfigUtils.config.CurrencyName}不足,开商店需要{ConfigUtils.config.OpenRequireMoney}");
                    }
                    break;
                case "set":
                    if (args.Parameters[1] == "buy")
                    {
                        skplr.SetBuyType();
                        args.Player.SendInfoMessage("请右键你要设置的箱子,将类型更改为 [收购]  （输入cancel停止操作）");
                    }
                    else if (args.Parameters[1] == "sell")
                    {
                        skplr.SetSellType();
                        args.Player.SendInfoMessage("请右键你要设置的箱子,将类型更改为 [出售]  （输入cancel停止操作）");
                    }
                    else
                    {
                        args.Player.SendInfoMessage("支持的类型为 buy(收购)  sell(出售)");
                    }
                    break;
                case "remove":
                    skplr.SetRemoveShopType();
                    args.Player.SendMessage("请敲击你的箱子,来移除一个箱子商店 （输入cancel停止操作）", Color.DarkTurquoise);
                    break;
                case "setitem":
                    args.Player.SendInfoMessage("请将需要设置的物品放置在指定箱子第一格后右击箱子 （输入cancel停止操作）");
                    skplr.SetUpitemType();
                    break;
                case "setprice":
                    skplr.SendInfoMessage("请敲击要设置的箱子");
                    skplr.SetPrice();
                    break;
            }
        }
        #endregion
        #region --BSAdmin--
        private void bsadmin(CommandArgs args)
        {
            var skplr = keepers.Find(p => p.Player.Name == args.Player.Name);
            var input = args.Parameters;
            if (input.Count < 1)
            {
                args.Player.SendErrorMessage("输入/bsadmin help 查看帮助信息");
                return;
            }
            int id = 0;
            switch (input[0])
            {
                case "help":
                    var helptext = new StringBuilder();
                    helptext.AppendLine("/bsadmin help 查看帮助页面");
                    helptext.AppendLine("/bsadmin list [玩家名] 列出该玩家的所有商店");
                    helptext.AppendLine("/bsadmin set [ID] [type] 设置指定商店的类型(type可选 sell buy common)");
                    helptext.AppendLine("/bsadmin setprice [ID] [Price] 设置指定ID商店的价格");
                    helptext.AppendLine("/bsadmin remove [ID] 移除指定ID的商店");
                    args.Player.SendMessage(helptext.ToString(), Color.DarkTurquoise);
                    break;
                case "list":
                    if (args.Parameters.Count<2)
                    {
                        args.Player.SendErrorMessage("正确用法 /bsadmin list [玩家名]");
                        return;
                    }
                    var keeperShopList = new StringBuilder();
                    keeperShopList.AppendLine($"玩家 [{input[1]}] 商店列表-->");
                    foreach (var item in shops)
                    {
                        if (item.Owner==input[1])
                        {
                            keeperShopList.AppendLine($"ID:{item.ID} 类型:{item.ReturnType()} 商品:[i:{item.GoodsID}] 价格:{item.GoodPrice}");
                        }
                    }
                    args.Player.SendMessage(keeperShopList.ToString(),Color.DarkTurquoise);
                    break;
                case "setprice":
                    int price = 0;
                    if (int.TryParse(args.Parameters[1], out id) && shops.Exists(s => s.ID == id))
                    {
                        var chest = shops.Find(s => s.ID == id);
                        if (int.TryParse(args.Parameters[2], out price)&&price>=0)
                        {
                            chest.GoodPrice = price;
                            args.Player.SendMessage($"成功设置 ID:{id} 号商店的价格为 {chest.GoodPrice}",Color.SpringGreen);
                            ConfigUtils.UpdateShops();
                        }
                        else {
                            args.Player.SendMessage("请输入正确的价格", Color.Crimson);
                        }
                    }
                    else
                    {
                        args.Player.SendMessage("请输入正确的数字", Color.Crimson);
                    }
                    break;
                case "remove":
                    if (int.TryParse(args.Parameters[1], out id) && shops.Exists(s => s.ID == id) && id > 0)
                    {
                        var chest = shops.Find(s => s.ID == id);
                        shops.Remove(chest);
                        args.Player.SendMessage($"成功移除 ID:{id} 号商店",Color.DarkOrange);
                        ConfigUtils.UpdateShops();
                    }
                    else {
                        args.Player.SendMessage("请输入正确的数字",Color.Crimson);
                    }
                    break;
                case "set":
                    if (int.TryParse(args.Parameters[1], out id) && shops.Exists(s => s.ID == id)&&id>0)
                    {
                        var chest = shops.Find(s => s.ID == id);
                        if (args.Parameters[2] == "buy")
                        {
                            chest.Type = ShopType.Buy;
                            args.Player.SendMessage($"成功设置 ID:{id} 的商店类型为 {chest.Type.ToString().Replace("buy", "收购")}",Color.SpringGreen);
                            ConfigUtils.UpdateShops();
                        }
                        else if (args.Parameters[2] == "sell")
                        {
                            chest.Type = ShopType.Sell;
                            args.Player.SendMessage($"成功设置 ID:{id} 的商店类型为 {chest.Type.ToString().Replace("sell", "出售")}", Color.SpringGreen);
                            ConfigUtils.UpdateShops();
                        }
                        else if (args.Parameters[2] == "common")
                        {
                            chest.Type = ShopType.Common;
                            args.Player.SendMessage($"成功设置 ID:{id} 的商店类型为 {chest.Type.ToString().Replace("common", "普通")}", Color.SpringGreen);
                            ConfigUtils.UpdateShops();
                        }
                        else
                        {
                            args.Player.SendMessage("无此商店类型",Color.Crimson);
                        }
                    }
                    else {
                        args.Player.SendErrorMessage("请输入正确的数字",Color.Crimson);
                    }
                    break;
            }
        }
        #endregion
        #region --Dispose--
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                ServerApi.Hooks.ServerJoin.Deregister(this, OnJoin);
                ServerApi.Hooks.ServerChat.Deregister(this, OnChat);
                ServerApi.Hooks.ServerLeave.Deregister(this, OnLeave);
                ServerApi.Hooks.NetGetData.Deregister(this, OnGetData);
                GetDataHandlers.PlaceChest -= OnPlaceChest;
                GetDataHandlers.TileEdit -= OnTileEdit;
                GeneralHooks.ReloadEvent -= OnReload;
            }
            base.Dispose(disposing);
        }
        #endregion
    }
}
